#ifndef FILE_TCP_H
#define FILE_TCP_H 1
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<deque>
#include<iterator>
#include<algorithm>
#include<cerrno>
#include<cstring>

#include<fcntl.h>
#include<sys/types.h>

#ifdef WIN32
#include"win32.h"
#else
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
#endif


//tcpwraper for general using ...

using namespace std;

class TcpHost
{
private:
  int sethost(const string& host, int port);
public:
  string host;
  int port;
  struct addrinfo *ai;
    
  explicit TcpHost(const string& h, int p);
  TcpHost& operator=(const TcpHost &r);
  TcpHost(const TcpHost&r);
  TcpHost();
  ~TcpHost();
};

class TcpAgent
{
protected:
  int fd;
  int recvtimeout, sendtimeout;//socket option
public:
  TcpAgent(int rto, int sto):fd(-1), recvtimeout(rto), sendtimeout(sto) {}
  
  ~TcpAgent() {
    close();
  }

  int is_epipe();

  int read(void *buf, int len);

  int read_all(string& str);
  
  int write(const void *buf, int len);
  
  int write(const string& str);
  
  int write_all(const void*buf, int len);

  int write_all(string& str);//do change str
  
  void close();

  void close(int s);
  
  void closewrite();
  
  void closeread();
  
};

class TcpClient : public TcpAgent
{
  string tohostname;
  int toport;
  int cnttimeout;
  int do_connect(int socket, const struct sockaddr *address, socklen_t address_len);
  
public:
  TcpClient(int to):TcpAgent(to, to), cnttimeout(to) {  }

  int connect(const TcpHost& tohost);

  int reconnect(const TcpHost& tohost);  
};

#endif

